using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ForumExplorer.Core.ObjectModel;
using ForumExplorer.Extension.Tagging;

namespace ForumExplorer.UI.Winforms
{
    public partial class ForumExplorer : Form
    {
        public ForumExplorer()
        {
            InitializeComponent();
            tagger = new Tagging();
            toolStripButtonLogin_Click(this, null);
            postID = 0;
        }

        private Tagging tagger;
        private int postID;
        private Thread[] searchResults;
        private string searchTag;

        private void ForumExplorer_Load(object sender, EventArgs e)
        {
            webBrowserForum.Navigate("http://forums.microsoft.com/msdn");
            foreach (DataRow dr in metadata.Sites.Rows)
            {
                TreeNode node = treeViewForums.Nodes.Add(dr["SiteName"] as string);
                node.Tag = dr;
                AddExpandNode(node);
            }
            msnSearchPanel1.searchButtonClicked += new global::ForumExplorer.Extension.MSNSearch.MSNSearchPanel.searchButtonClickedDelegate(MSNSearchPanelSearchClicked);
        }

        void taggingPanel1_listBoxIndexChanged(object sender, EventArgs e, int postID)
        {
            webBrowserForum.Navigate("http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=" + postID.ToString());
            tabControlMainPanel.SelectTab(0);
        }

        private void AddExpandNode(TreeNode node)
        {
            TreeNode expandnode = node.Nodes.Add("Expand");
        }

        private ForumMetaData metadata = new ForumMetaData();

        private void treeViewForums_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            if (true == webBrowserForum.IsBusy)
            {
                e.Cancel = true;
                return;
            }

            TreeView tv = sender as TreeView;
            TreeNode node = e.Node;
            if (1 == node.Nodes.Count && 0 == String.Compare(node.Nodes[0].Text, "Expand", true))
            {
                DataRow row = node.Tag as DataRow;
                if (null != row)
                {
                    if (0 == String.Compare(row.Table.TableName, "Sites", false))
                    {
                        node.Nodes.Clear();
                        string url = String.Format("http://forums.microsoft.com/{0}/default.aspx?SiteID={1}", node.Text, node.Tag.ToString());
                        node.Text += " (expanding...)";
                        webBrowserForum.Tag = node;
                        webBrowserForum.Navigate(url);
                    }
                    else if (0 == String.Compare(row.Table.TableName, "Groups", false))
                    {
                        node.Nodes.Clear();
                        string filter = String.Format("GroupID={0}", row["GroupID"].ToString());
                        DataRow[] forums = metadata.Forums.Select(filter);
                        foreach (DataRow forumrow in forums)
                        {
                            TreeNode child = node.Nodes.Add(forumrow["ForumName"].ToString());
                            child.Tag = forumrow;
                        }
                        node.Expand();
                    }
                }
            }
        }

        private void webBrowserForum_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            //if it's a thread, get the tags for the thread and display them to the user
            ForumUtility util = new ForumUtility();
            toolStripTextBoxWebAddress.Text = webBrowserForum.Url.AbsoluteUri;
            postID = util.GetPostIDFromURL(webBrowserForum.Url.AbsoluteUri);          
            string[] tags = tagger.GetTagsForThreadID(postID);
            flowLayoutPanelCurrentTags.Controls.Clear();
			if (tags != null)
			{
				foreach (string s in tags)
				{
					LinkLabel l = new LinkLabel();
					l.Font = new Font(l.Font, FontStyle.Bold);
					l.Name = s;
					l.Text = s;
					l.Click += new EventHandler(TagLink_Click);
					flowLayoutPanelCurrentTags.Controls.Add(l);
				}
			}

            TreeNode node = webBrowserForum.Tag  as TreeNode;
			if (node != null)
			{
				DataRow siterow = node.Tag as DataRow;

				if (0 == String.Compare(siterow.Table.TableName, "Sites", true) &&
					false == (bool)siterow["SiteIsLoaded"])
				{
					node.Nodes.Clear();
					TreeNode child;

					Parser p = new Parser();
					p.ParseForumList(webBrowserForum.Document, metadata.Groups, metadata.Forums, siterow["SiteName"].ToString());

					String filter = String.Format("SiteID={0}", siterow["SiteID"]);

					foreach (DataRow row in metadata.Groups.Select(filter))
					{
						child = node.Nodes.Add(row["GroupName"].ToString());
						child.Tag = row;
						AddExpandNode(child);
					}
					node.Expand();
					node.Text = siterow["SiteName"].ToString();
					siterow["SiteIsLoaded"] = true;

				}
			}
            
        }

        /// <summary>
        /// This is the action that is committed whenever somebody clicks on a LinkLabel that is a tag
        /// in the main browser control.  This will bring up a search results pane of all of the
        /// subjects of threads that have been clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
		void TagLink_Click ( object sender, EventArgs e )
		{
			this.buttonSearch.Enabled = false;
			this.textBoxCustomTagSearch.Enabled = false;
			LinkLabel l = (LinkLabel)sender;
            searchTag = l.Text;
			l.Enabled = false;
			tagger.GetThreadsForTagCompleted += new EventHandler<Tagging.GetThreadsForTagEventArgs>(tagger_GetThreadsForTagCompleted);
			tagger.GetThreadsforTag(l, searchTag);
		}

		void tagger_GetThreadsForTagCompleted ( object sender, Tagging.GetThreadsForTagEventArgs e )
		{
			tagger.GetThreadsForTagCompleted -= new EventHandler<Tagging.GetThreadsForTagEventArgs>(tagger_GetThreadsForTagCompleted);
			if (this.InvokeRequired)
			{
				this.BeginInvoke(new EventHandler<Tagging.GetThreadsForTagEventArgs>(tagger_GetThreadsForTagCompleted), new object[] { sender, e });
			}
			else
			{
				try
				{
					searchResults = e.Threads;
					tabControl1.SelectTab(1);
					listBoxTagSearchResults.Items.Clear();

                    //added: joemorel, 10/25
                    //if the "Show Answered Questions" box isn't checked, trim out the unanswered questions from the searchResults
                    if (checkBoxHideAnswered.Checked)
                    {
                        List<Thread> tempThreads = new List<Thread>();
                        foreach (Thread t in searchResults)
                        {
                            if (!t.answered)
                                tempThreads.Add(t);
                        }
                        searchResults = tempThreads.ToArray();
                    }

					tabControl1.SelectedTab.Text = "Search: \"" + e.SearchText + "\"";
					if (searchResults != null)
					{
						for (int i = 0; i < searchResults.Length; i++)
						{
							listBoxTagSearchResults.Items.Add(searchResults[i].subject);
						}
					}
				}
				finally
				{
					Control control = e.State as Control;
					if (control != null)
					{
						control.Enabled = true;
					}
					else
					{
						buttonSearch.Enabled = true;
					}
					this.textBoxCustomTagSearch.Enabled = true;
				}
			}
		}

        private void treeViewForums_AfterSelect(object sender, TreeViewEventArgs e)
        {
            DataRow row = e.Node.Tag as DataRow;

            string url = null;
            if (0 == String.Compare(row.Table.TableName, "Sites", false))
            {
                url = String.Format("http://forums.microsoft.com/{0}/default.aspx?SiteID={1}", row["SiteName"], row["SiteID"].ToString());
            }
            else if (0 == String.Compare(row.Table.TableName, "Groups", false))
            {
                DataRow[] siterows = metadata.Sites.Select(String.Format("SiteID={0}", row["SiteID"].ToString()));
                url = String.Format("http://forums.microsoft.com/{0}/default.aspx?ForumGroupID={1}&SiteID={2}", siterows[0]["SiteName"], row["GroupID"], siterows[0]["SiteID"].ToString());
            }
            else if (0 == String.Compare(row.Table.TableName, "Forums", false))
            {
                DataRow[] grouprows = metadata.Groups.Select(String.Format("GroupID={0}", row["GroupID"].ToString()));
                DataRow[] siterows = metadata.Sites.Select(String.Format("SiteID={0}", grouprows[0]["SiteID"].ToString()));
                url = String.Format("http://forums.microsoft.com/{0}/ShowForum.aspx?ForumID={1}&SiteID={2}", siterows[0]["SiteName"], row["ForumID"], siterows[0]["SiteID"].ToString());
            }

            if (null != url)
            {
                webBrowserForum.Tag = e.Node;
                webBrowserForum.Navigate(url);
            }
        }

        private void treeViewForums_BeforeSelect(object sender, TreeViewCancelEventArgs e)
        {
            if (true == webBrowserForum.IsBusy)
            {
                e.Cancel = true;
                return;
            }
        }

		private String userName;

        private void toolStripButtonLogin_Click(object sender, EventArgs e)
        {
            if (toolStripButtonLogin.Text == "Login")
            {
                Login SignInDialogBox = new Login();
                DialogResult result = SignInDialogBox.ShowDialog();
                if (result == DialogResult.OK)
                {
                    toolStripStatusLabelLogin.Text = "Connecting to msmoderators.com..";
                    toolStripProgressBar1.Visible = true;
                    toolStrip1.Refresh();
                    userName = SignInDialogBox.username();
                    string password = SignInDialogBox.password();
                    if (userName == String.Empty)
                    {
                        MessageBox.Show("Please enter a valid username.");
                        toolStripButtonLogin_Click(sender, e);
                    }
                    else if (password == String.Empty)
                    {
                        MessageBox.Show("Please enter a valid password.");
                        toolStripButtonLogin_Click(sender, e);
                    }

					tagger.SetCredentialsCompleted += new EventHandler<EventArgs>(tagger_SetCredentialsCompleted);
                    tagger.SetCredentials(userName, password);
					toolStripButtonLogin.Enabled = false;
                }
            }
        }

		/// <revisionHistory>
		/// <revision author="Peter Ritchie" date="22-Oct-06">
		/// Created
		/// </revision>
		/// </revisionHistory>
		/// TODO: create a state member and use that member in UpdateControls
		/// to enable/disable controls during asychronous operations.
		void tagger_SetCredentialsCompleted ( object sender, EventArgs e )
		{
			if (InvokeRequired)
			{
				this.BeginInvoke(new EventHandler<EventArgs>(tagger_SetCredentialsCompleted), new Object[] {sender, e});
			}
			else
			{
				tagger.SetCredentialsCompleted -= new EventHandler<EventArgs>(tagger_SetCredentialsCompleted);
				toolStripButtonLogin.Enabled = false;
				toolStripProgressBar1.Visible = false;
				toolStrip1.Refresh();
				if (!tagger.isLoggedIn)
				{
					MessageBox.Show("Your username/password was denied.  Please make sure you have a working Internet connection and verify your username and password are correct.", "Login Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
				else
				{
					toolStripStatusLabelLogin.Text = "Logged in to msmoderators.com as " + userName;
					toolStripButtonLogin.Text = "Logout";
					//populate the "Commonly Used Tags" panel
					string[] tags = tagger.GetTopTags();
					Button b;
					foreach (string s in tags)
					{
						b = new Button();
						b.Text = s;
						b.Name = s;
						b.Click += new EventHandler(topTagButton_Click);
						flowLayoutPanelCommonTags.Controls.Add(b);
						listBoxTagList.Items.Add(s);
					}
				}
			}
		}

        void topTagButton_Click(object sender, EventArgs e)
        {
            Button b = (Button)sender;
            if (postID != 0)
            {
                //go ahead and trim the forum name from the document title
                string[] subjectSplit = webBrowserForum.DocumentTitle.Split(new Char[] {'-'});
                string subject = String.Empty;
                for (int i = 0; i < (subjectSplit.Length - 1); i++)
                    subject = subject + subjectSplit[i];
                tagger.TagThread(b.Text, subject, postID.ToString());
                webBrowserForum.Navigate(webBrowserForum.Url);
            }
            else
                MessageBox.Show("You must be on a forums thread to add a tag.", "Tagging Error", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);

        }

        private void toolStripButtonStop_Click(object sender, EventArgs e)
        {
            webBrowserForum.Stop();
        }

        private void toolStripButtonBack_Click(object sender, EventArgs e)
        {
            if (webBrowserForum.CanGoBack)
                webBrowserForum.GoBack();
        }

        private void toolStripButtonRefresh_Click(object sender, EventArgs e)
        {
            webBrowserForum.Refresh();
        }

        private void MSNSearchPanelSearchClicked(object sender, EventArgs e)
        {
            webBrowserSearchResults.Navigate(msnSearchPanel1.searchControl.GetURL());
        }

        private void webBrowserForum_Navigated(object sender, WebBrowserNavigatedEventArgs e)
        {
            webBrowserForum.Parent.Parent.Parent.Text = webBrowserForum.DocumentTitle;
            tabControlMainPanel.SelectedIndex = 0;
        }

        private void webBrowserSearchResults_Navigated(object sender, WebBrowserNavigatedEventArgs e)
        {
            webBrowserSearchResults.Parent.Text = webBrowserSearchResults.DocumentTitle;
            tabControlMainPanel.SelectedIndex = 1;
        }

        private void toolStripButtonHome_Click(object sender, EventArgs e)
        {
            webBrowserForum.Navigate("http://forums.microsoft.com/msdn");
        }

		/// <revisionHistory>
		/// <revision author="Peter Ritchie" date="22-Oct-06">
		/// Added null reference checks
		/// </revision>
		/// </revisionHistory>
		private void webBrowserForum_Navigating ( object sender, WebBrowserNavigatingEventArgs e )
        {
			if (this.Parent != null && this.Parent.Parent != null && this.Parent.Parent.Parent != null)
			{
				this.Parent.Parent.Parent.Text = "Loading...";
			}
        }

        private void linkLabelAddNewTag_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            if ((postID != 0) && (textBoxNewTag.Text != String.Empty))
            {
                //go ahead and trim the forum name from the document title
                string[] subjectSplit = webBrowserForum.DocumentTitle.Split(new Char[] { '-' });
                string subject = String.Empty;
                for (int i = 0; i < (subjectSplit.Length - 1); i++)
                    subject = subject + subjectSplit[i];
                tagger.TagThread(textBoxNewTag.Text, subject, postID.ToString());
                webBrowserForum.Navigate(webBrowserForum.Url);
            }
            else if(postID == 0)
                MessageBox.Show("You must be on a forums thread to add a new tag.", "Tagging Error", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
            else
                MessageBox.Show("Please enter a tag in the text box to tag this thread.", "Tagging Error", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);

        }

        /// <summary>
        /// When the something in the search results box is clicked, navigate to that thread.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listBoxTagSearchResults_SelectedIndexChanged(object sender, EventArgs e)
        {
            webBrowserForum.Navigate("http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=" + searchResults[listBoxTagSearchResults.SelectedIndex].threadID.ToString());
            tabControlMainPanel.SelectTab(0);
        }

		/// <revisionHistory>
		/// <revision author="Peter Ritchie" date="22-Oct-06">
		/// Reduced
		/// </revision>
		/// </revisionHistory>
		private static bool IsSubject ( Thread t, string test )
        {
            return t.subject == test;
        }

        private void NavigateBrowser()
        {
            webBrowserForum.Navigate(toolStripTextBoxWebAddress.Text);
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            NavigateBrowser();
        }

		/// <revisionHistory>
		/// <revision author="Peter Ritchie" date="22-Oct-06">
		/// Updated
		/// </revision>
		/// </revisionHistory>
		private void buttonSearch_Click ( object sender, EventArgs e )
        {
            if (textBoxCustomTagSearch.Text == String.Empty)
                searchTag = (string)listBoxTagList.SelectedItem;
            else
            {
                searchTag = textBoxCustomTagSearch.Text;
                textBoxCustomTagSearch.Text = String.Empty;
            }
            try
            {
                tabControl1.SelectTab(1);
                tabControl1.SelectedTab.Text = "Searching...";
				tagger.GetThreadsForTagCompleted += new EventHandler<Tagging.GetThreadsForTagEventArgs>(tagger_GetThreadsForTagCompleted);
				this.buttonSearch.Enabled = false;
				this.textBoxCustomTagSearch.Enabled = false;
				tagger.GetThreadsforTag(this.buttonSearch, searchTag);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
				this.textBoxCustomTagSearch.Enabled = true;
				this.buttonSearch.Enabled = true;
			}
        }

		/// <revisionHistory>
		/// <revision author="Peter Ritchie" date="22-Oct-06">
		/// Created
		/// </revision>
		/// </revisionHistory>
		private void listBoxTagList_SelectedIndexChanged ( object sender, EventArgs e )
		{
			UpdateControls();
		}

		/// <revisionHistory>
		/// <revision author="Peter Ritchie" date="22-Oct-06">
		/// Created
		/// </revision>
		/// </revisionHistory>
		private void textBoxCustomTagSearch_TextChanged ( object sender, EventArgs e )
		{
			UpdateControls();
		}

		/// <summary>
		/// Call when visible appearance of a control depends on some state and that
		/// state may have changed.
		/// </summary>
		/// <revisionHistory>
		/// <revision author="Peter Ritchie" date="22-Oct-06">
		/// Created
		/// </revision>
		/// </revisionHistory>
		private void UpdateControls()
		{
			buttonSearch.Enabled = !String.IsNullOrEmpty(textBoxCustomTagSearch.Text) || listBoxTagList.SelectedItems.Count > 0;
		}

		private void tabPageQuestionInfo_Layout ( object sender, LayoutEventArgs e )
		{
			UpdateControls();
		}

		private void toolStrip1_Resize ( object sender, EventArgs e )
		{
			toolStripTextBoxWebAddress.Width = this.Width - toolStripButtonGo.Width - toolStripTextBoxWebAddress.Control.Left - toolStripTextBoxWebAddress.Padding.Right - toolStripButtonGo.Padding.Left - toolStripButtonGo.Margin.Left - toolStripTextBoxWebAddress.Margin.Right - 10;
		}

		private void toolStrip1_LayoutCompleted ( object sender, EventArgs e )
		{
			toolStrip1_Resize(this, EventArgs.Empty);
		}

        private void checkBoxHideAnswered_CheckedChanged(object sender, EventArgs e)
        {
            try
            {
                tabControl1.SelectTab(1);
                tabControl1.SelectedTab.Text = "Searching...";
                tagger.GetThreadsForTagCompleted += new EventHandler<Tagging.GetThreadsForTagEventArgs>(tagger_GetThreadsForTagCompleted);
                this.buttonSearch.Enabled = false;
                this.textBoxCustomTagSearch.Enabled = false;
                tagger.GetThreadsforTag(this.buttonSearch, searchTag);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                this.textBoxCustomTagSearch.Enabled = true;
                this.buttonSearch.Enabled = true;
            }
        }
    }
}